home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-10 | 28.0 KB | 1,275 lines |
- /*
- * File: fsys.r
- * Contents: close, exit, getenv, open, read, reads, remove, rename, [save],
- * seek, stop, [system], where, write, writes, [getch, getche, kbhit]
- */
-
- #if MICROSOFT || SCO_XENIX
- #define BadCode
- #endif /* MICROSOFT || SCO_XENIX */
-
- #ifdef XENIX_386
- #define register
- #endif /* XENIX_386 */
- /*
- * The following code is operating-system dependent [@fsys.01]. Include
- * system-dependent files and declarations.
- */
-
- #if PORT
- /* nothing to do */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || ATARI_ST || MSDOS || MVS || OS2 || UNIX || VM || VMS
- /* nothing to do */
- #endif /* AMIGA || ATARI_ST || ... */
-
- #if MACINTOSH
- #if MPW
- #define isatty(fd) (!ioctl((fd), FIOINTERACTIVE))
- #define fflush(f) 0
- #endif /* MPW */
- #endif /* MACINTOSH */
-
- /*
- * End of operating-system specific code.
- */
-
-
- "close(f) - close file f."
-
- function{1} close(f)
-
- if !is:file(f) then
- runerr(105, f)
-
- abstract {
- return file ++ integer
- }
-
- body {
- FILE *fp;
-
- fp = BlkLoc(f)->file.fd;
-
- /*
- * Close f, using fclose, pclose, or wclose as appropriate.
- */
-
-
- #if ARM || OS2 || UNIX || VMS
- /*
- * Close pipe if pipes are supported.
- */
-
- if (BlkLoc(f)->file.status & Fs_Pipe) {
- BlkLoc(f)->file.status = 0;
- return C_integer((pclose(fp) >> 8) & 0377);
- }
- else
- #endif /* ARM || OS2 || UNIX || VMS */
-
- fclose(fp);
- BlkLoc(f)->file.status = 0;
-
- /*
- * Return the closed file.
- */
- return f;
- }
- end
-
-
- "exit(i) - exit process with status i, which defaults to 0."
-
- function{} exit(status)
- if !def:C_integer(status, NormalExit) then
- runerr(0)
- inline {
- c_exit((int)status);
- }
- end
-
-
- "getenv(s) - return contents of environment variable s."
-
- #ifndef EnvVars
- function{0} getenv(s)
- abstract {
- return empty_type
- }
- inline {
- fail;
- }
- #else /* EnvVars */
- function{0,1} getenv(s)
-
- /*
- * Make a C-style string out of s
- */
- if !cnv:C_string(s) then
- runerr(103,s)
- abstract {
- return string
- }
-
- inline {
- register char *p;
- long l;
-
- if ((p = getenv(s)) != NULL) { /* get environment variable */
- l = strlen(p);
- Protect(p = alcstr(p,l),runerr(0));
- return string(l,p);
- }
- else /* fail if not in environment */
- fail;
-
- }
- #endif /* EnvVars */
- end
-
-
- #ifdef OpenAttributes
- "open(fname, spec, attrstring) - open file fname with specification spec."
- function{0,1} open(fname, spec, attrstring)
- #else /* OpenAttributes */
- "open(fname, spec) - open file fname with specification spec."
- function{0,1} open(fname, spec)
- #endif /* OpenAttributes */
- declare {
- tended struct descrip filename;
- }
-
- /*
- * fopen and popen require a C string.
- */
- if !cnv:C_string(fname) then
- runerr(103, fname)
-
- /*
- * spec defaults to "r".
- */
- if !def:tmp_string(spec, letr) then
- runerr(103, spec)
-
- #ifdef OpenAttributes
- /*
- * Convert attrstr to a string, defaulting to "".
- */
- if !def:C_string(attrstring, emptystr);
- #endif /* OpenAttributes */
-
- abstract {
- return file
- }
-
- body {
- register word slen;
- register int i;
- register char *s;
- int status;
- char mode[4];
- extern FILE *fopen();
- FILE *f;
- struct b_file *fl;
-
-
- /*
- * The following code is operating-system dependent [@fsys.02]. Make
- * declarations as needed for opening files.
- */
-
- #if PORT
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || MACINTOSH
- /* nothing is needed */
- #endif /* AMIGA || MACINTOSH */
-
- #if ARM
- extern FILE *popen(const char *, const char *);
- extern int pclose(FILE *);
- #endif /* ARM */
-
- #if ATARI_ST || MSDOS || OS2 || MVS || VM
- char untranslated;
- #endif /* ATARI_ST || MS-DOS || ... */
-
- #if MACINTOSH
- #if LSC
- char untranslated;
- #endif /* LSC */
- #endif /* MACINTOSH */
-
- #if OS2 || UNIX || VMS
- extern FILE *popen();
- #endif /* OS2 || UNIX || VMS */
-
- /*
- * End of operating-system specific code.
- */
-
- status = 0;
-
- /*
- * The following code is operating-system dependent [@fsys.03]. Provide
- * declaration for untranslated line-termination mode, if supported.
- */
-
- #if PORT
- /* nothing to do */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA
- /* translated mode could be supported, but is not now */
- #endif /* AMIGA */
-
- #if ARM || UNIX || VMS
- /* nothing to do */
- #endif /* ARM || UNIX || VMS */
-
- #if ATARI_ST || MSDOS || MVS || OS2 || VM
- untranslated = 0;
- #endif /* ATARI_ST || MSDOS || ... */
-
- #if MACINTOSH
- #if LSC
- untranslated = 0;
- #endif /* LSC */
- #endif /* MACINTOSH */
-
- /*
- * End of operating-system specific code.
- */
-
- /*
- * Scan spec, setting appropriate bits in status. Produce a
- * run-time error if an unknown character is encountered.
- */
- s = StrLoc(spec);
- slen = StrLen(spec);
- for (i = 0; i < slen; i++) {
- switch (*s++) {
- case 'a':
- case 'A':
- status |= Fs_Write|Fs_Append;
- continue;
- case 'b':
- case 'B':
- status |= Fs_Read|Fs_Write;
- continue;
- case 'c':
- case 'C':
- status |= Fs_Create|Fs_Write;
- continue;
- case 'r':
- case 'R':
- status |= Fs_Read;
- continue;
- case 'w':
- case 'W':
- status |= Fs_Write;
- continue;
-
- /*
- * The following code is operating-system dependent [@fsys.04]. Handle
- * untranslated line-terminator mode, pipes, and/or window modes if supported.
- */
-
- #if PORT
- case 't':
- case 'T':
- case 'u':
- case 'U':
- continue; /* no-op */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA
- case 't':
- case 'T':
- case 'u':
- case 'U':
- continue; /* no-op */
- #endif /* AMIGA */
-
- #if ARM || UNIX || VMS
- case 't':
- case 'T':
- case 'u':
- case 'U':
- continue; /* no-op */
- case 'p':
- case 'P':
- status |= Fs_Pipe;
- continue;
- #endif /* ARM || UNIX || VMS */
-
- #if ATARI_ST || MSDOS || OS2 || SASC
- case 't':
- case 'T':
- untranslated = 0;
-
- #if OS2
- case 'p':
- case 'P':
- status |= Fs_Pipe;
- continue;
- #endif /* OS2 */
-
- #ifdef RecordIO
- status &= ~Fs_Record;
- #endif /* RecordIO */
-
- continue;
- case 'u':
- case 'U':
- untranslated = 1;
-
- #ifdef RecordIO
- status &= ~Fs_Record;
- #endif /* RecordIO */
-
- continue;
- #endif /* ATARI_ST || MSDOS || ... */
-
- #ifdef RecordIO
- case 's':
- case 'S':
- untranslated = 1;
- status |= Fs_Record;
- continue;
- #endif /* RecordIO */
-
- #if MACINTOSH
- #if LSC
- case 't':
- case 'T':
- untranslated = 0;
- continue;
- case 'u':
- case 'U':
- untranslated = 1;
- continue;
- #endif /* LSC */
- #endif /* MACINTOSH */
-
- /*
- * End of operating-system specific code.
- */
-
-
- default:
- runerr(209, spec);
- }
- }
-
- /*
- * Construct a mode field for fopen/popen.
- */
- mode[0] = '\0';
- mode[1] = '\0';
- mode[2] = '\0';
- mode[3] = '\0';
-
- if ((status & (Fs_Read|Fs_Write)) == 0) /* default: read only */
- status |= Fs_Read;
- if (status & Fs_Create)
- mode[0] = 'w';
- else if (status & Fs_Append)
- mode[0] = 'a';
- else if (status & Fs_Read)
- mode[0] = 'r';
- else
- mode[0] = 'w';
-
- /*
- * The following code is operating-system dependent [@fsys.05]. Handle open
- * modes.
- */
-
- #if PORT
- if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write))
- mode[1] = '+';
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || ARM || UNIX || VMS
- if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write))
- mode[1] = '+';
- #endif /* AMIGA || ARM || UNIX || VMS */
-
- #if ATARI_ST
- if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write)) {
- mode[1] = '+';
- mode[2] = untranslated ? 'b' : 'a';
- }
- else mode[1] = untranslated ? 'b' : 'a';
- #endif /* ATARI_ST */
-
- #if MSDOS || OS2
- if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write)) {
- mode[1] = '+';
- mode[2] = untranslated ? 'b' : 't';
- }
- else mode[1] = untranslated ? 'b' : 't';
- #endif /* MSDOS || OS2 */
-
- #if MACINTOSH
- #if LSC
- untranslated = 0;
- #endif /* LSC */
- #endif /* MACINTOSH */
-
- #if MVS || VM
- if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write)) {
- mode[1] = '+';
- mode[2] = untranslated ? 'b' : 0;
- }
- else mode[1] = untranslated ? 'b' : 0;
- #endif /* MVS || VM */
-
- /*
- * End of operating-system specific code.
- */
-
- /*
- * Open the file with fopen or popen.
- */
-
- #ifdef OpenAttributes
- #if SASC
- #ifdef RecordIO
- f = afopen(fname, mode, status & Fs_Record ? "seq" : "",
- attrstring);
- #else /* RecordIO */
- f = afopen(fname, mode, "", attrstring);
- #endif /* RecordIO */
- #endif /* SASC */
-
- #else /* OpenAttributes */
-
-
- #if ARM || OS2 || UNIX || VMS
- if (status & Fs_Pipe) {
- if (status != (Fs_Read|Fs_Pipe) && status != (Fs_Write|Fs_Pipe))
- runerr(209, spec);
- f = popen(fname, mode);
- }
- else
- #endif /* ARM || OS2 || UNIX || VMS */
-
- f = fopen(fname, mode);
- #endif /* OpenAttributes */
-
- /*
- * Fail if the file cannot be opened.
- */
- if (f == NULL)
- fail;
-
- #if MACINTOSH
- #if MPW
- /* Set file type and creator. */
- {
- FInfo info;
-
- if (getfinfo(fname,0,&info) == 0) {
- if (status & Fs_Write && info.fdType == 0 && info.fdCreator == 0) {
- info.fdType = 'TEXT';
- info.fdCreator = 'MPS ';
- setfinfo(fname,0,&info);
- }
- }
- }
- #endif /* MPW */
- #endif /* MACINTOSH */
-
- /*
- * Return the resulting file value.
- */
- StrLen(filename) = strlen(fname);
- StrLoc(filename) = fname;
-
- Protect(fl = alcfile(f, status, &filename), runerr(0));
- return file(fl);
- }
- end
-
-
- "read(f) - read line on file f."
-
- function{0,1} read(f)
- /*
- * Default f to &input.
- */
- if is:null(f) then
- inline {
- f = input;
- }
- else if !is:file(f) then
- runerr(105, f)
-
- abstract {
- return string
- }
-
- body {
- register word slen, rlen;
- register char *sp;
- int status;
- static char sbuf[MaxReadStr];
- FILE *fp;
-
- /*
- * Get a pointer to the file and be sure that it is open for reading.
- */
- fp = BlkLoc(f)->file.fd;
- status = BlkLoc(f)->file.status;
- if ((status & Fs_Read) == 0)
- runerr(212, f);
-
- #ifdef StandardLib
- if (status & Fs_Writing) {
- fseek(fp, 0L, SEEK_CUR);
- BlkLoc(f)->file.status &= ~Fs_Writing;
- }
- BlkLoc(f)->file.status |= Fs_Reading;
- #endif /* StandardLib */
-
- /*
- * Use getstrg to read a line from the file, failing if getstrg
- * encounters end of file. [[ What about -2?]]
- */
- StrLen(result) = 0;
- do {
-
- #ifdef RecordIO
- if ((slen = (status & Fs_Record ? getrec(sbuf, MaxReadStr, fp) :
- getstrg(sbuf, MaxReadStr, fp)))
- == -1) fail;
- #else /* RecordIO */
- if ((slen = getstrg(sbuf,MaxReadStr,fp)) == -1)
- fail;
- #endif /* RecordIO */
-
- /*
- * Allocate the string read and make result a descriptor for it.
- */
- rlen = slen < 0 ? (word)MaxReadStr : slen;
- Protect(sp = alcstr(sbuf,rlen), runerr(0));
- if (StrLen(result) == 0)
- StrLoc(result) = sp;
- StrLen(result) += rlen;
- } while (slen < 0);
- return result;
- }
- end
-
-
- "reads(f,i) - read i characters on file f."
-
- function{0,1} reads(f,i)
- /*
- * Default f to &input.
- */
- if is:null(f) then
- inline {
- f = input;
- }
- else if !is:file(f) then
- runerr(105, f)
-
- /*
- * i defaults to 1 (read a single character)
- */
- if !def:C_integer(i,1L) then
- runerr(101, i)
-
- abstract {
- return string
- }
-
- body {
- long tally;
- char *s;
- int status;
- FILE *fp;
-
- /*
- * Get a pointer to the file and be sure that it is open for reading.
- */
- fp = BlkLoc(f)->file.fd;
- status = BlkLoc(f)->file.status;
- if ((status & Fs_Read) == 0)
- runerr(212, f);
-
- #ifdef StandardLib
- if (status & Fs_Writing) {
- fseek(fp, 0L, SEEK_CUR);
- BlkLoc(f)->file.status &= ~Fs_Writing;
- }
- BlkLoc(f)->file.status |= Fs_Reading;
- #endif /* StandardLib */
-
- /*
- * Be sure that a positive number of bytes is to be read.
- */
- if (i <= 0) {
- irunerr(205, i);
-
- errorfail;
- }
-
- /*
- * For now, assume we can read the full number of bytes.
- */
- Protect(StrLoc(result) = alcstr(NULL, i), runerr(0));
- StrLen(result) = 0;
-
- #if AMIGA
- /*
- * The following code is special for Lattice 4.0 -- it was different
- * for Lattice 3.10. It probably won't work correctly with other
- * C compilers.
- */
- if (IsInteractive(_ufbs[fileno(fp)].ufbfh)) {
- if ((i = read(fileno(fp),StrLoc(result),i)) <= 0)
- fail;
- StrLen(result) = i;
- /*
- * We may not have used the entire amount of storage we reserved.
- */
- MMStr(DiffPtrs(StrLoc(result) + i, strfree));
- strtotal += DiffPtrs(StrLoc(result) + i, strfree);
- strfree = StrLoc(result) + i;
- return result;
- }
- #endif /* AMIGA */
-
- tally = longread(StrLoc(result),sizeof(char),i,fp);
-
- if (tally == 0)
- fail;
- StrLen(result) = tally;
- /*
- * We may not have used the entire amount of storage we reserved.
- */
- MMStr(DiffPtrs(StrLoc(result) + tally, strfree));
- strtotal += DiffPtrs(StrLoc(result) + tally, strfree);
- strfree = StrLoc(result) + tally;
- return result;
- }
- end
-
-
- "remove(s) - remove the file named s."
-
- function{0,1} remove(s)
-
- /*
- * Make a C-style string out of s
- */
- if !cnv:C_string(s) then
- runerr(103,s)
- abstract {
- return null
- }
-
- inline {
- if (unlink(s) != 0)
- fail;
- return nulldesc;
- }
- end
-
-
- "rename(s1,s2) - rename the file named s1 to have the name s2."
-
- function{0,1} rename(s1,s2)
-
- /*
- * Make C-style strings out of s1 and s2
- */
- if !cnv:C_string(s1) then
- runerr(103,s1)
- if !cnv:C_string(s2) then
- runerr(103,s2)
-
- abstract {
- return null
- }
-
- body {
- /*
- * The following code is operating-system dependent [@fsys.06]. Rename the
- * file, and fail if unsuccessful.
- */
-
- #if PORT
- /* need something */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || ARM || ATARI_ST || MACINTOSH || MSDOS || MVS || OS2 || VM || VMS
- {
- if (rename(s1,s2) != 0)
- fail;
- }
- #endif /* AMIGA || ARM || ATARI_ST ... */
-
- #if UNIX
- if (link(s1,s2) != 0)
- fail;
- if (unlink(s1) != 0) {
- unlink(s2); /* try to undo partial rename */
- fail;
- }
- #endif /* UNIX */
-
- /*
- * End of operating-system specific code.
- */
-
- return nulldesc;
- }
- end
-
- #ifdef ExecImages
-
- "save(s) - save the run-time system in file s"
-
- function{0,1} save(s)
-
- if !cnv:C_string(s) then
- runerr(103,s)
-
- abstract {
- return integer
- }
-
- body {
- char sbuf[MaxCvtLen];
- int f, fsz;
-
- dumped = 1;
-
- /*
- * Open the file for the executable image.
- */
- f = creat(s, 0777);
- if (f == -1)
- fail;
- fsz = wrtexec(f);
- /*
- * It happens that most wrtexecs don't check the system call return
- * codes and thus they'll never return -1. Nonetheless...
- */
- if (fsz == -1)
- fail;
- /*
- * Return the size of the data space.
- */
- return C_integer fsz;
- }
- end
- #endif /* ExecImages */
-
-
- "seek(f,i) - seek to offset i in file f."
- " [[ What about seek error ? ]] "
-
- function{0,1} seek(f,o)
-
- /*
- * f must be a file
- */
- if !is:file(f) then
- runerr(105,f)
-
- /*
- * o must be an integer and defaults to 1.
- */
- if !def:C_integer(o,1L) then
- runerr(0)
-
- abstract {
- return file
- }
-
- body {
- FILE *fd;
-
- fd = BlkLoc(f)->file.fd;
- if (BlkLoc(f)->file.status == 0)
- fail;
-
-
- if (o > 0) {
- if (fseek(fd, o - 1, SEEK_SET) == -1)
- fail;
- }
- else {
- if (fseek(fd, o, SEEK_END) == -1)
- fail;
- }
- #ifdef StandardLib
- BlkLoc(f)->file.status &= ~(Fs_Reading | Fs_Writing);
- #endif /* StandardLib */
- return f;
- }
- end
-
-
- #ifdef SystemFnc
-
- "system(s) - execute string s as a system command."
-
- function{1} system(s)
- /*
- * Make a C-style string out of s
- */
- if !cnv:C_string(s) then
- runerr(103,s)
-
- abstract {
- return integer
- }
-
- inline {
- /*
- * Pass the C string to the system() function and return
- * the exit code of the command as the result of system().
- * Note, the expression on a "return" may not have side effects,
- * so the exit code must be returned via a variable.
- */
- C_integer i;
-
-
- /*
- * The following code is operating-system dependent [@fsys.12]. Perform system
- * call. Should not get here unless system(s) is supported.
- */
-
- #if PORT
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || OS2 || UNIX
- i = ((system(s) >> 8) & 0377);
- #endif /* AMIGA || OS2 || ... */
-
- #if MSDOS
- #if HIGHC_386
- i = (C_integer)system(s);
- #else /* HIGHC_386 */
- i = ((system(s) >> 8) & 0377);
- #endif /* HIGHC_386 */
- #endif /* MSDOS */
-
- #if ARM
- i = (C_integer)system(s);
- #endif /* ARM */
-
- #if ATARI_ST || VMS
- i = system(s);
- #endif /* ATARI_ST || VMS */
-
- #if MACINTOSH
- /* Should not get here */
- #endif /* MACINTOSH */
-
- #if MVS || VM
- #if SASC && MVS
- {
- char *wprefix;
- wprefix = malloc(strlen(s)+5);
- /* hope this will do no harm... */
- sprintf(wprefix,"tso:%s",s);
- i = (C_integer)system(wprefix);
- free(wprefix);
- }
- #else /* SASC && MVS */
- i = (C_integer)system(s);
- #endif /* SASC && MVS */
- #endif /* MVS || VM */
-
- /*
- * End of operating-system specific code.
- */
- return C_integer i;
- }
- end
-
- #endif /* SystemFnc */
-
-
- "where(f) - return current offset position in file f."
-
- function{0,1} where(f)
-
- if !is:file(f) then
- runerr(105,f)
-
- abstract {
- return integer
- }
-
- body {
- FILE *fd;
- long ftell();
- long pos;
-
- fd = BlkLoc(f)->file.fd;
-
- if ((BlkLoc(f)->file.status == 0))
- fail;
-
-
- pos = ftell(fd) + 1;
- #ifdef StandardLib
- if (pos == 0)
- fail; /* may only be effective on ANSI systems */
- #endif /* StandardLib */
-
- return C_integer pos;
- }
- end
-
- /*
- * stop(), write(), and writes() differ in whether they stop the program
- * and whether they output newlines. The macro GenWrite is used to
- * produce all three functions.
- */
- #define False 0
- #define True 1
-
- #begdef DefaultFile(error_out)
- inline {
- #if error_out
- if ((k_errout.status & Fs_Write) == 0)
- runerr(213);
- else {
- f = k_errout.fd;
- }
- #else /* error_out */
- if ((k_output.status & Fs_Write) == 0)
- runerr(213);
- else {
- f = k_output.fd;
- }
- #endif /* error_out */
- }
- #enddef /* DefaultFile */
-
- #begdef Finish(retvalue, nl, terminate)
- #if nl
- /*
- * Append a newline to the file and flush it.
- */
- #ifdef RecordIO
- if (status & Fs_Record)
- flushrec(f);
- else
- #endif /* RecordIO */
- putc('\n', f);
-
- if (ferror(f))
- runerr(214);
- fflush(f);
-
- #endif /* nl */
-
- #if terminate
- c_exit(ErrorExit);
- #else /* terminate */
- return retvalue;
- #endif /* terminate */
- #enddef /* Finish */
-
- #begdef GenWrite(name, nl, terminate)
-
- #name "(a,b,...) - write arguments"
- #if !nl
- " without newline terminator"
- #endif /* nl */
- #if terminate
- " (starting on error output) and stop"
- #endif /* terminate */
- "."
-
- #if terminate
- function {} name(x[nargs])
- #else /* terminate */
- function {1} name(x[nargs])
- #endif /* terminate */
-
- declare {
- FILE *f;
- word status =
- #if terminate
- k_errout.status;
- #else /* terminate */
- k_output.status;
- #endif /* terminate */
-
- #ifdef BadCode
- struct descrip temp;
- #endif /* BadCode */
- }
-
- #if terminate
- abstract {
- return empty_type
- }
- #endif /* terminate */
-
- len_case nargs of {
- 0: {
- #if !terminate
- abstract {
- return null
- }
- #endif /* terminate */
- DefaultFile(terminate)
- body {
- Finish(nulldesc, nl, terminate)
- }
- }
-
- default: {
- #if !terminate
- abstract {
- return type(x)
- }
- #endif /* terminate */
- /*
- * See if we need to start with the default file.
- */
- if !is:file(x[0]) then
- DefaultFile(terminate)
-
- body {
- tended struct descrip t;
- register word n;
-
- /*
- * Loop through the arguments.
- */
- for (n = 0; n < nargs; n++) {
- if (is:file(x[n])) { /* Current argument is a file */
- #if nl
- /*
- * If this is not the first argument, output a newline to the
- * current file and flush it.
- */
- if (n > 0) {
-
- /*
- * Append a newline to the file and flush it.
- */
- #ifdef RecordIO
- if (status & Fs_Record)
- flushrec(f);
- else
- #endif /* RecordIO */
-
- putc('\n', f);
-
- if (ferror(f))
- runerr(214);
- fflush(f);
- }
- #endif /* nl */
- /*
- * Switch the current file to the file named by the current
- * argument providing it is a file.
- */
- status = BlkLoc(x[n])->file.status;
- if ((status & Fs_Write) == 0)
- runerr(213, x[n]);
- f = BlkLoc(x[n])->file.fd;
- }
- else {
- /*
- * Convert the argument to a string, defaulting to a empty
- * string.
- */
- if (!def:tmp_string(x[n],emptystr,t))
- runerr(109, x[n]);
-
- /*
- * Output the string.
- */
- #ifdef RecordIO
- if ((status & Fs_Record ? putrec(f, &t) :
- putstr(f, &t)) == Failed)
- #else /* RecordIO */
- if (putstr(f, &t) == Failed)
- #endif /* RecordIO */
- runerr(214, x[n]);
- }
- }
-
- Finish(x[n-1], nl, terminate)
- }
- }
- }
- end
- #enddef /* GenWrite */
-
- GenWrite(stop, True, True) /* stop(s, ...) - write message and stop */
- GenWrite(write, True, False) /* write(s, ...) - write with new-line */
- GenWrite(writes, False, False) /* writes(s, ...) - write with no new-line */
-
- #ifdef KeyboardFncs
-
- "getch() - return a character from console."
-
- function{0,1} getch()
- abstract {
- return string;
- }
- body {
- int i;
-
- i = getch();
- if (i<0 || i>255)
- fail;
- return string(1, &allchars[FromAscii(i) & 0xFF]);
- }
- end
-
- "getche() -- return a character from console with echo."
-
- function{0,1} getche()
- abstract {
- return string;
- }
- body {
- int i;
-
- i = getche();
- if (i<0 || i>255)
- fail;
- return string(1, &allchars[FromAscii(i) & 0xFF]);
- }
- end
-
-
- "kbhit() -- Check to see if there is a keyboard character waiting to be read."
-
- function{0,1} kbhit()
- abstract {
- return null
- }
- inline {
- if (kbhit()) {
- return nulldesc;
- }
- else fail;
- }
- end
- #endif /* KeyboardFncs */
-
- "chdir(s) - change working directory to s."
- function{0,1} chdir(s)
-
- if !cnv:C_string(s) then
- runerr(103,s)
- abstract {
- return null
- }
- inline {
-
- /*
- * The following code is operating-system dependent [@fsys.01].
- * Change directory.
- */
-
- #if PORT
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || ARM || MACINTOSH || MVS || VM
- runerr(121);
- #endif /* AMIGA || ARM || MACINTOSH ... */
-
- #if ATARI_ST || MSDOS || OS2 || UNIX || VMS
- #if MWC
- runerr(121);
- #else /* MWC */
- if (chdir(s) != 0)
- fail;
- return nulldesc;
- #endif /* MWC */
- #endif /* ATARI_ST || MSDOS || ... */
-
- /*
- * End of operating-system specific code.
- */
- }
- end
-
- #if UNIX
- "delay(i) - delay for i milliseconds."
-
- function{1} delay(n)
-
- if !cnv:C_integer(n) then
- runerr(101,n)
- abstract {
- return null
- }
-
- inline {
-
- /*
- * The following code is operating-system dependent [@fsys.01]. Delay for n
- * milliseconds.
- */
-
- #ifdef FD_SET
- #define FD_NULL ((fd_set *) 0)
- #else /* FD_SET */
- #define FD_NULL ((long *) 0)
- #endif /* FD_SET */
- struct timeval t;
- t.tv_sec = n / 1000;
- t.tv_usec = (n % 1000) * 1000;
- select(1, FD_NULL, FD_NULL, FD_NULL, &t);
-
-
- return nulldesc;
-
- }
- end
- #endif /* UNIX */
-
- "flush(f) - flush file f."
-
- function{1} flush(f)
- if !is:file(f) then
- runerr(105, f)
- abstract {
- return type(f)
- }
-
- body {
- FILE *fp;
-
-
- fp = BlkLoc(f)->file.fd;
- fflush(fp);
-
- /*
- * Return the flushed file.
- */
- return f;
- }
- end
-